CC moved to deprecated. The rest was really removed.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="AnalysisUIOptions">
+ <option name="CUSTOM_SCOPE_NAME" value="Project Source Files" />
+ <option name="SHOW_STRUCTURE" value="true" />
+ </component>
+ <component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true">
+ <generated>
+ <config projectName="gpsbabel" targetName="GPSBabel" />
+ <config projectName="gpsbabel" targetName="check" />
+ </generated>
+ </component>
+ <component name="CMakeSettings">
+ <configurations>
+ <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
+ </configurations>
+ </component>
+ <component name="ChangeListManager">
+ <list default="true" id="3a284925-7de6-4867-82b2-c979bff68de5" name="Default" comment="Move format-specific code into formspec.h, start constexpr work.">
+ <change beforePath="$PROJECT_DIR$/.idea/encodings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/defs.h" beforeDir="false" afterPath="$PROJECT_DIR$/defs.h" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/garmin_fit.cc" beforeDir="false" afterPath="$PROJECT_DIR$/garmin_fit.cc" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_de.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_de.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_es.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_es.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_fr.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_fr.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_hu.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_hu.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_it.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_it.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/coretool/gpsbabel_ru.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/coretool/gpsbabel_ru.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_de.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_de.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_es.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_es.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_fr.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_fr.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_hu.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_hu.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_it.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_it.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/gui/gpsbabelfe_ru.ts" beforeDir="false" afterPath="$PROJECT_DIR$/gui/gpsbabelfe_ru.ts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/hiketech.cc" beforeDir="false" afterPath="$PROJECT_DIR$/hiketech.cc" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/core/datetime.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/core/datetime.h" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/core/file.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/core/file.h" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/core/logging.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/core/logging.h" afterDir="false" />
+ </list>
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ClangdSettings">
+ <option name="formatViaClangd" value="false" />
+ </component>
+ <component name="DatabaseView">
+ <option name="SHOW_INTERMEDIATE" value="true" />
+ <option name="GROUP_DATA_SOURCES" value="true" />
+ <option name="GROUP_SCHEMA" value="true" />
+ <option name="GROUP_CONTENTS" value="false" />
+ <option name="SORT_POSITIONED" value="false" />
+ <option name="SHOW_EMPTY_GROUPS" value="false" />
+ <option name="AUTO_SCROLL_FROM_SOURCE" value="false" />
+ <option name="HIDDEN_KINDS">
+ <set />
+ </option>
+ <expand />
+ <select />
+ </component>
+ <component name="ExecutionTargetManager" SELECTED_TARGET="CMakeBuildProfile:Debug" />
+ <component name="FavoritesManager">
+ <favorites_list name="gpsbabel" />
+ </component>
+ <component name="FindInProjectRecents">
+ <findStrings>
+ <find>kkkkkk</find>
+ <find>flush</find>
+ <find>facd</find>
+ <find>isDLE</find>
+ <find>n_clp</find>
+ <find>n_trk</find>
+ <find>rcv_len</find>
+ <find>checksum</find>
+ <find>recv_byte</find>
+ <find>malloc</find>
+ <find>alloc</find>
+ <find>read_package</find>
+ <find>mkgmtime</find>
+ <find>free</find>
+ <find>latopt</find>
+ <find>time</find>
+ <find>xcalloc</find>
+ <find>strncpy</find>
+ <find>class</find>
+ <find>unknown_alt</find>
+ <find>format_specific</find>
+ <find>format_spec</find>
+ <find>forward</find>
+ <find>color</find>
+ <find>"unit_conversions.h"</find>
+ <find>#include "unit_conversions.h"</find>
+ <find>cet_ucs4_to_char</find>
+ <find>8_to_any</find>
+ <find>stdout</find>
+ <find>time_t</find>
+ </findStrings>
+ <replaceStrings>
+ <replace>#include "src/core/unit_conversions.h"</replace>
+ </replaceStrings>
+ </component>
+ <component name="Git.Settings">
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="IgnoredFileRootStore">
+ <option name="generatedRoots">
+ <set>
+ <option value="$PROJECT_DIR$/.idea" />
+ </set>
+ </option>
+ </component>
+ <component name="OCFindUsagesOptions" text="true" ivars="false" properties="true" derivedClasses="false" />
+ <component name="OCResolveContextSettings">
+ <option name="configuration" value="0-GPSBabel" />
+ </component>
+ <component name="ProjectConfigurationFiles">
+ <option name="files">
+ <list>
+ <option value="$PROJECT_DIR$/.idea/dictionaries/robertlipe.xml" />
+ </list>
+ </option>
+ </component>
+ <component name="ProjectFrameBounds">
+ <option name="x" value="61" />
+ <option name="y" value="23" />
+ <option name="width" value="1364" />
+ <option name="height" value="699" />
+ </component>
+ <component name="ProjectId" id="1TDw5AKrnBp2YgRTkxMwl4qS16A" />
+ <component name="PropertiesComponent">
+ <property name="Git.Branch.Popup.ShowAllRemotes" value="true" />
+ <property name="WebServerToolWindowFactoryState" value="false" />
+ <property name="node.js.detected.package.eslint" value="true" />
+ <property name="node.js.detected.package.tslint" value="true" />
+ <property name="node.js.path.for.package.eslint" value="project" />
+ <property name="node.js.path.for.package.tslint" value="project" />
+ <property name="node.js.selected.package.eslint" value="(autodetect)" />
+ <property name="node.js.selected.package.tslint" value="(autodetect)" />
+ <property name="run.code.analysis.last.selected.profile" value="pProject Default" />
+ <property name="settings.editor.selected.configurable" value="language.cpp.clangd" />
+ </component>
+ <component name="RunDashboard">
+ <option name="ruleStates">
+ <list>
+ <RuleState>
+ <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+ </RuleState>
+ <RuleState>
+ <option name="name" value="StatusDashboardGroupingRule" />
+ </RuleState>
+ </list>
+ </option>
+ </component>
+ <component name="RunManager" selected="CMake Application.Build All">
+ <configuration name="Build All" type="CMakeRunConfiguration" factoryName="Application" PASS_PARENT_ENVS_2="true" CONFIG_NAME="Debug" EXPLICIT_BUILD_TARGET_NAME="all">
+ <method v="2">
+ <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
+ </method>
+ </configuration>
+ <configuration name="GPSBabel" type="CMakeRunConfiguration" factoryName="Application" PASS_PARENT_ENVS_2="true" PROJECT_NAME="gpsbabel" TARGET_NAME="GPSBabel" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="gpsbabel" RUN_TARGET_NAME="GPSBabel">
+ <method v="2">
+ <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
+ </method>
+ </configuration>
+ <configuration name="check" type="CMakeRunConfiguration" factoryName="Application" PASS_PARENT_ENVS_2="true" PROJECT_NAME="gpsbabel" TARGET_NAME="check" CONFIG_NAME="Debug">
+ <method v="2">
+ <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
+ </method>
+ </configuration>
+ <list>
+ <item itemvalue="CMake Application.Build All" />
+ <item itemvalue="CMake Application.GPSBabel" />
+ <item itemvalue="CMake Application.check" />
+ </list>
+ </component>
+ <component name="SvnConfiguration">
+ <configuration />
+ </component>
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="3a284925-7de6-4867-82b2-c979bff68de5" name="Default" comment="" />
+ <created>1532152300466</created>
+ <option name="number" value="Default" />
+ <option name="presentableId" value="Default" />
+ <updated>1532152300466</updated>
+ <workItem from="1532152303018" duration="495000" />
+ <workItem from="1532153154653" duration="2501000" />
+ <workItem from="1543808962549" duration="778000" />
+ <workItem from="1543810521878" duration="9719000" />
+ <workItem from="1544241723516" duration="190000" />
+ <workItem from="1544247988998" duration="209000" />
+ <workItem from="1545190229123" duration="9870000" />
+ <workItem from="1545203719072" duration="7758000" />
+ <workItem from="1545531824698" duration="5264000" />
+ <workItem from="1547440985444" duration="50000" />
+ <workItem from="1547441099366" duration="8230000" />
+ <workItem from="1547453970564" duration="494000" />
+ <workItem from="1550765983922" duration="653000" />
+ <workItem from="1550766762635" duration="13000" />
+ <workItem from="1556408944794" duration="12127000" />
+ <workItem from="1559448360028" duration="522000" />
+ <workItem from="1572677805570" duration="98000" />
+ <workItem from="1572677976846" duration="1540000" />
+ <workItem from="1572801370457" duration="4032000" />
+ <workItem from="1573007798512" duration="207000" />
+ </task>
+ <task id="LOCAL-00001" summary="Move format-specific code into formspec.h, start constexpr work.">
+ <created>1556420216496</created>
+ <option name="number" value="00001" />
+ <option name="presentableId" value="LOCAL-00001" />
+ <option name="project" value="LOCAL" />
+ <updated>1556420216497</updated>
+ </task>
+ <task id="LOCAL-00002" summary="Auto-move unit conversions into src/core.">
+ <created>1556422562996</created>
+ <option name="number" value="00002" />
+ <option name="presentableId" value="LOCAL-00002" />
+ <option name="project" value="LOCAL" />
+ <updated>1556422562996</updated>
+ </task>
+ <task id="LOCAL-00003" summary="Move format-specific code into formspec.h, start constexpr work.">
+ <created>1556423058600</created>
+ <option name="number" value="00003" />
+ <option name="presentableId" value="LOCAL-00003" />
+ <option name="project" value="LOCAL" />
+ <updated>1556423058601</updated>
+ </task>
+ <option name="localTasksCounter" value="4" />
+ <servers />
+ </component>
+ <component name="TodoView">
+ <todo-panel id="selected-file">
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ <todo-panel id="all">
+ <are-packages-shown value="true" />
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ </component>
+ <component name="TypeScriptGeneratedFilesManager">
+ <option name="version" value="1" />
+ </component>
+ <component name="Vcs.Log.Tabs.Properties">
+ <option name="TAB_STATES">
+ <map>
+ <entry key="MAIN">
+ <value>
+ <State>
+ <option name="COLUMN_ORDER" />
+ </State>
+ </value>
+ </entry>
+ </map>
+ </option>
+ <option name="RECENT_FILTERS">
+ <map>
+ <entry key="Branch">
+ <value>
+ <list />
+ </value>
+ </entry>
+ <entry key="User">
+ <value>
+ <list />
+ </value>
+ </entry>
+ </map>
+ </option>
+ </component>
+ <component name="VcsManagerConfiguration">
+ <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="CHECK_NEW_TODO" value="false" />
+ <MESSAGE value="Auto-move unit conversions into src/core." />
+ <MESSAGE value="Move format-specific code into formspec.h, start constexpr work." />
+ <option name="LAST_COMMIT_MESSAGE" value="Move format-specific code into formspec.h, start constexpr work." />
+ <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="true" />
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ScopeChooserConfigurable.UI">
+ <settings>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ </states>
+ </component>
+</project>
\ No newline at end of file
${MINIMAL_FMTS} gtm.cc gpsutil.cc pcx.cc
skytraq.cc holux.cc tmpro.cc tpg.cc tpo.cc
xcsv.cc tiger.cc easygps.cc
- saroute.cc navicache.cc psitrex.cc delgpl.cc
+ saroute.cc navicache.cc delgpl.cc
ozi.cc text.cc html.cc netstumbler.cc
igc.cc brauniger_iq.cc shape.cc hiketech.cc glogbook.cc
vcf.cc lowranceusr.cc an1.cc tomtom.cc
energympro.cc mynav.cc ggv_bin.cc globalsat_sport.cc geojson.cc qstarz_bl_1000.cc
)
-#DEPRECATED_FMTS=cetus.cc copilot.cc gpspilot.cc magnav.cc psp.cc gcdb.cc quovadis.cc gpilots.cc geoniche.cc palmdoc.cc hsa_ndv.cc coastexp.cc pathaway.cc coto.cc msroute.cc mag_pdb.cc axim_gpb.cc delbin.cc google.cc
+#DEPRECATED_FMTS=cetus.cc copilot.cc gpspilot.cc magnav.cc psp.cc gcdb.cc quovadis.cc gpilots.cc geoniche.cc palmdoc.cc hsa_ndv.cc coastexp.cc pathaway.cc coto.cc msroute.cc mag_pdb.cc axim_gpb.cc delbin.cc google.cc psitrex.cc
#DEPRECATED_HEADERS=geo.h quovadis.h
#DEPRECATED_SHAPE=pdbfile.cc
ALL_FMTS=$$MINIMAL_FMTS gtm.cc gpsutil.cc pcx.cc \
skytraq.cc holux.cc tmpro.cc tpg.cc tpo.cc \
xcsv.cc tiger.cc easygps.cc \
- saroute.cc navicache.cc psitrex.cc delgpl.cc \
+ saroute.cc navicache.cc delgpl.cc \
ozi.cc text.cc html.cc netstumbler.cc \
igc.cc brauniger_iq.cc shape.cc hiketech.cc glogbook.cc \
vcf.cc lowranceusr.cc an1.cc tomtom.cc \
mtk_locus.cc googledir.cc mapbar_track.cc mapfactor.cc f90g_track.cc \
energympro.cc mynav.cc ggv_bin.cc globalsat_sport.cc geojson.cc qstarz_bl_1000.cc
-DEPRECATED_FMTS=cetus.cc copilot.cc gpspilot.cc magnav.cc psp.cc gcdb.cc quovadis.cc gpilots.cc geoniche.cc palmdoc.cc hsa_ndv.cc coastexp.cc pathaway.cc coto.cc msroute.cc mag_pdb.cc axim_gpb.cc delbin.cc google.cc
+DEPRECATED_FMTS=cetus.cc copilot.cc gpspilot.cc magnav.cc psp.cc gcdb.cc quovadis.cc gpilots.cc geoniche.cc palmdoc.cc hsa_ndv.cc coastexp.cc pathaway.cc coto.cc msroute.cc mag_pdb.cc axim_gpb.cc delbin.cc google.cc psitrex.cc
DEPRECATED_HEADERS=geo.h quovadis.h
DEPRECATED_SHAPE=pdbfile.cc
skytraq.o \
holux.o tmpro.o tpg.o tpo.o \
tiger.o easygps.o \
- saroute.o navicache.o psitrex.o delgpl.o \
+ saroute.o navicache.o delgpl.o \
text.o html.o netstumbler.o \
igc.o brauniger_iq.o shape.o hiketech.o glogbook.o \
vcf.o lowranceusr.o an1.o tomtom.o \
position.o: position.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
src/core/optional.h grtcirc.h position.h filter.h
-psitrex.o: psitrex.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
- inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- garmin_tables.h
qstarz_bl_1000.o: qstarz_bl_1000.cc qstarz_bl_1000.h defs.h config.h \
zlib/zlib.h zlib/zconf.h formspec.h inifile.h gbfile.h session.h \
src/core/datetime.h src/core/optional.h format.h src/core/logging.h
--- /dev/null
+/*
+ Access to PsiTrex text files.
+ Based on information provided by Ian Cowley.
+
+ Copyright (C) 2003 Mark Bradley, mrcb.gpsb@osps.net
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <cctype> // for isspace
+#include <cstdio> // for sscanf, EOF, size_t
+#include <cstdlib> // for atof, atoi
+#include <cstring> // for strcmp, strlen, strcpy
+#include <ctime> // for gmtime
+
+#include <QtCore/QChar> // for QChar
+#include <QtCore/QLatin1String> // for QLatin1String
+#include <QtCore/QString> // for QString
+#include <QtCore/QtGlobal> // for foreach, uint
+
+#include "defs.h"
+#include "garmin_tables.h" // for gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, PCX
+#include "gbfile.h" // for gbfprintf, gbfeof, gbfile, gbfgetc, gbfclose, gbfgets, gbfopen, gbfputs
+#include "src/core/datetime.h" // for DateTime
+
+
+#define MYNAME "PSITREX"
+
+enum psit_tokenSep_type {
+ ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */
+ EOL, /* don't skip spaces and tabs to start; end on EOL */
+ comma, /* skip spaces & tabs to start; ends on comma or EOL */
+ whitespace, /* skip spaces & tabs to start; ends on white space or EOL */
+ wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */
+};
+
+struct psit_icon_mapping_t {
+ int value;
+ const char* icon;
+};
+
+static gbfile* psit_file_in;
+static gbfile* psit_file_out;
+static short_handle mkshort_handle;
+
+/* 2 = not written any tracks out
+ 1 = change of track to write out track header
+ 0 = in the middle of writing out track datapoints, so don't write a header */
+static int psit_track_state = 2;
+
+static char psit_current_token[256];
+
+static char* snlen;
+
+static
+QVector<arglist_t> psit_args = {
+ /* {"snlen", &snlen, "Length of generated shortnames",
+ NULL, ARGTYPE_INT, "1", NULL }, */
+};
+
+/* Taken from PsiTrex 1.13 */
+static
+const psit_icon_mapping_t psit_icon_value_table[] = {
+ { 0x00, "anchor" },
+ { 0x06, "dollar" },
+ { 0x07, "fish" },
+ { 0x08, "fuel" },
+ { 0x0a, "house" },
+ { 0x0b, "knife" },
+ { 0x0d, "mug" },
+ { 0x0e, "skull" },
+ { 0x12, "wpt_dot" },
+ { 0x13, "wreck" },
+ { 0x15, "mob" },
+ { 0x0096, "boat_ramp" },
+ { 0x0097, "camp" },
+ { 0x0098, "restrooms" },
+ { 0x0099, "showers" },
+ { 0x009a, "drinking_wtr" },
+ { 0x009b, "phone" },
+ { 0x009c, "1st_aid" },
+ { 0x009d, "info" },
+ { 0x009e, "parking" },
+ { 0x009f, "park" },
+ { 0x00a0, "picnic" },
+ { 0x00a1, "scenic" },
+ { 0x00a2, "skiing" },
+ { 0x00a3, "swimming" },
+ { 0x00a4, "dam" },
+ { 0x00a6, "danger" },
+ { 0x00a9, "ball" },
+ { 0x00aa, "car" },
+ { 0x00ab, "deer" },
+ { 0x00ac, "shpng_cart" },
+ { 0x00ad, "lodging" },
+ { 0x00ae, "mine" },
+ { 0x00af, "trail_head" },
+ { 0x00b0, "truck_stop" },
+ { 0x00b2, "flag" },
+ { 0x2005, "golf" },
+ { 0x2006, "sml_cty" },
+ { 0x2007, "med_cty" },
+ { 0x2008, "lrg_cty" },
+ { 0x200c, "amuse_pk" },
+ { 0x200d, "bowling" },
+ { 0x200e, "car_rental" },
+ { 0x200f, "car_repair" },
+ { 0x2010, "fastfood" },
+ { 0x2011, "fitness" },
+ { 0x2012, "movie" },
+ { 0x2013, "museum" },
+ { 0x2014, "pharmacy" },
+ { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */
+ { 0x2016, "post_ofc" },
+ { 0x2017, "rv_park" },
+ { 0x2018, "school" },
+ { 0x2019, "stadium" },
+ { 0x201a, "store" },
+ { 0x201b, "zoo" },
+ { 0x201c, "gas_plus" },
+ { 0x201d, "faces" },
+ { 0x2022, "weigh_sttn" },
+ { 0x2023, "toll_booth" },
+ { 0x2029, "bridge" },
+ { 0x202a, "building" },
+ { 0x202b, "cemetery" },
+ { 0x202c, "church" },
+ { 0x202e, "crossing" },
+ { 0x2032, "oil_field" },
+ { 0x2033, "tunnel" },
+ { 0x2035, "forest" },
+ { 0x2036, "summit" },
+ { 0x203f, "geocache" },
+ { 0x2040, "geocache_fnd" },
+ { 0x4000, "airport" },
+ { 0x4007, "tall_tower" },
+ { 0x4008, "short_tower" },
+ { 0x4009, "glider" },
+ { 0x400a, "ultralight" },
+ { 0x400b, "parachute" },
+ { 0x4012, "seaplane" },
+ { -1, nullptr }
+};
+
+static const char*
+psit_find_desc_from_icon_number(const int icon)
+{
+ for (const psit_icon_mapping_t* i = psit_icon_value_table; i->icon; i++) {
+ if (icon == i->value) {
+ return i->icon;
+ }
+ }
+ return "";
+}
+
+static int
+psit_find_icon_number_from_desc(const char* desc)
+{
+ int def_icon = 18;
+
+ if (!desc) {
+ return def_icon;
+ }
+
+ for (const psit_icon_mapping_t* i = psit_icon_value_table; i->icon; i++) {
+ if (case_ignore_strcmp(desc,i->icon) == 0) {
+ return i->value;
+ }
+ }
+ if (atoi(desc) > 0) {
+ return atoi(desc);
+ }
+ return def_icon;
+}
+
+static void
+psit_rd_init(const QString& fname)
+{
+ psit_file_in = gbfopen(fname, "r", MYNAME);
+}
+
+static void
+psit_rd_deinit()
+{
+ gbfclose(psit_file_in);
+}
+
+static void
+psit_wr_init(const QString& fname)
+{
+ psit_file_out = gbfopen(fname, "w", MYNAME);
+}
+
+static void
+psit_wr_deinit()
+{
+ gbfclose(psit_file_out);
+}
+
+/*
+ * get characters until and including terminating NULL from psit_file_in
+ * and write into buf.
+ */
+static void
+psit_getToken(gbfile* psit_file, char* buf, size_t sz, psit_tokenSep_type delimType)
+{
+ int c = -1;
+
+ *buf = 0;
+
+ if (delimType != EOL) {
+ while ((c = gbfgetc(psit_file)) != EOF) {
+ if (!isspace(c)) {
+ break;
+ }
+ }
+ }
+
+ if (gbfeof(psit_file)) {
+ return;
+ }
+
+ if (delimType == EOL) {
+ c = gbfgetc(psit_file);
+ }
+
+ if (c == '#') {
+ if (gbfgets(buf, sz, psit_file) == nullptr) {
+ *buf = 0;
+ return;
+ }
+ /* use recursion to skip multiple comment lines or just to return the next token */
+ psit_getToken(psit_file, buf, sz, delimType);
+ return;
+ }
+
+ if ((delimType == EOL) || (delimType == ltrimEOL)) {
+ *buf = c;
+ buf++;
+ gbfgets(buf, sz-1, psit_file);
+ return;
+ }
+
+ while (sz--) {
+ *buf++ = c;
+ if ((c = gbfgetc(psit_file)) == EOF) {
+ *buf = 0;
+ return;
+ }
+ if (((c == 0) || isspace(c)) &&
+ ((delimType == whitespace) || (delimType == wscomma))) {
+ *buf = 0;
+ return;
+ }
+ if (((delimType == comma) || (delimType == wscomma)) &&
+ (c == ',')) {
+ *buf = 0;
+ return;
+ }
+ }
+}
+
+
+/*
+ * test if a token is known
+ *
+ */
+static int
+psit_isKnownToken(char* buf)
+{
+ if (strcmp(buf, "Track:") == 0) {
+ return 0;
+ }
+ if (strcmp(buf, "Route:") == 0) {
+ return 0;
+ }
+ if (strcmp(buf, "Waypoint:") == 0) {
+ return 0;
+ }
+ if (strcmp(buf, "Map:") == 0) {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * read in from file a waypoint record
+ * MRCB
+ */
+static void
+psit_waypoint_r(gbfile* psit_file, Waypoint**)
+{
+ if (strlen(psit_current_token) > 0) {
+ auto* thisWaypoint = new Waypoint;
+
+ thisWaypoint->latitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ thisWaypoint->longitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ if (psit_current_token[0] == '*') {
+ thisWaypoint->altitude = unknown_alt;
+ } else {
+ thisWaypoint->altitude = atof(psit_current_token);
+ }
+
+ /* the name */
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ rtrim(psit_current_token);
+ thisWaypoint->shortname = psit_current_token;
+ thisWaypoint->description = "";
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
+ rtrim(psit_current_token);
+ /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */
+ /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */
+ int garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token);
+ thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX);
+
+ waypt_add(thisWaypoint);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
+ }
+}
+
+/*
+ * write out to file a waypoint record
+ * MRCB
+ */
+static void
+psit_waypoint_w(gbfile* psit_file, const Waypoint* wpt)
+{
+ gbfprintf(psit_file, "%11.6f,%11.6f,",
+ wpt->latitude,
+ wpt->longitude);
+
+ if (wpt->altitude == unknown_alt) {
+ gbfprintf(psit_file, "********,");
+ } else
+ gbfprintf(psit_file, "%8.2f,",
+ wpt->altitude);
+
+ const char* ident = global_opts.synthesize_shortnames ?
+ mkshort(mkshort_handle, "WPT", false) :
+ xstrdup(wpt->shortname);
+
+ gbfprintf(psit_file, " %-6s, ", ident);
+ xfree(ident);
+
+ int icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX);
+
+ if (get_cache_icon(wpt) && wpt->icon_descr.compare(QLatin1String("Geocache Found")) != 0) {
+ icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX);
+ }
+
+ ident = psit_find_desc_from_icon_number(icon);
+ if (strlen(ident) == 0) {
+ gbfprintf(psit_file, "%1d\n", icon);
+ } else {
+ gbfprintf(psit_file, "%s\n", ident);
+ }
+
+}
+
+static void
+psit_waypoint_w_wrapper(const Waypoint* wpt)
+{
+ psit_waypoint_w(psit_file_out, wpt);
+}
+
+/*
+ * read in from file a route record
+ * MRCB
+ */
+static void
+psit_route_r(gbfile* psit_file, route_head** rte)
+{
+ char rtename[256];
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
+
+ if (strlen(psit_current_token) == 0) {
+ strcpy(rtename, "ROUTE");
+ } else {
+ strcpy(rtename, psit_current_token);
+ }
+
+ rtrim(rtename);
+
+ auto* rte_head = new route_head;
+ rte_head->rte_name = rtename;
+ route_add_head(rte_head);
+ *rte = rte_head;
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
+
+ while (psit_isKnownToken(psit_current_token) != 0) {
+ if (strlen(psit_current_token) > 0) {
+ auto* thisWaypoint = new Waypoint;
+
+ thisWaypoint->latitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ thisWaypoint->longitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ if (psit_current_token[0] == '*') {
+ thisWaypoint->altitude = unknown_alt;
+ } else {
+ thisWaypoint->altitude = atof(psit_current_token);
+ }
+
+ /* the name */
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ rtrim(psit_current_token);
+ thisWaypoint->shortname = psit_current_token;
+ thisWaypoint->description = "";
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
+ rtrim(psit_current_token);
+ /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */
+ /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */
+ int garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token);
+ thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX);
+
+ route_add_wpt(rte_head, thisWaypoint);
+
+ if (gbfeof(psit_file)) {
+ break;
+ }
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
+ } else {
+ break;
+ }
+ }
+}
+
+/*
+ * write out to file a route header
+ * MRCB
+ */
+static void
+psit_routehdr_w(gbfile* psit_file, const route_head* rte)
+{
+ QString rname;
+
+ /* total nodes (waypoints) this route */
+ //if (rte->waypoint_list.next) {
+ if (true) {
+ // this test doesn't do what I w ant i.e test if this is a valid
+ // route - treat as a placeholder for now .
+ time_t uniqueValue = 0;
+ unsigned int rte_datapoints = 0;
+ foreach (const Waypoint* testwpt, rte->waypoint_list) {
+ if (rte_datapoints == 0) {
+ uniqueValue = testwpt->GetCreationTime().toTime_t();
+ }
+ rte_datapoints++;
+ }
+
+ if (uniqueValue == 0) {
+ uniqueValue = current_time().toTime_t();
+ }
+
+ /* route name */
+ if (rte->rte_name.isEmpty()) {
+ rname = QString("Route%1").arg((uint) uniqueValue, 4, 16, QChar('0'));
+ } else {
+ rname = rte->rte_name;
+ }
+ /* check for psitrex comment sign; replace with '$' */
+ rname = rname.replace(QChar('#'), QChar('$'));
+
+ gbfputs(QString("Route: %1\n").arg(rname), psit_file);
+ }
+}
+
+static void
+psit_routehdr_w_wrapper(const route_head* rte)
+{
+ psit_routehdr_w(psit_file_out, rte);
+}
+
+
+/*
+ * read in from file a track record
+ * MRCB
+ */
+static void
+psit_track_r(gbfile* psit_file, route_head**)
+{
+ char trkname[256];
+
+ struct tm tmTime;
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
+ if (strlen(psit_current_token) == 0) {
+ strcpy(trkname, "TRACK");
+ } else {
+ strcpy(trkname, psit_current_token);
+ }
+
+ rtrim(trkname);
+
+ unsigned int trk_num = 0;
+ route_head* track_head = nullptr;
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
+
+ while (psit_isKnownToken(psit_current_token) != 0) {
+ if (strlen(psit_current_token) > 0) {
+ auto* thisWaypoint = new Waypoint;
+
+ thisWaypoint->latitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ thisWaypoint->longitude = atof(psit_current_token);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
+ if (psit_current_token[0] == '*') {
+ thisWaypoint->altitude = unknown_alt;
+ } else {
+ thisWaypoint->altitude = atof(psit_current_token);
+ }
+
+ /* date portion of the date time DD/MM/YY */
+ psit_getToken(psit_file, psit_current_token,
+ sizeof(psit_current_token), whitespace);
+ sscanf(psit_current_token, "%02d/%02d/%02d",
+ &(tmTime.tm_mday) , &(tmTime.tm_mon),
+ &(tmTime.tm_year));
+
+ /* years are less 1900 in the tm struct */
+ tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100);
+ /* months are 0 to 11 in the tm struct */
+ tmTime.tm_mon--;
+ /* time portion of the date time hh:mm:ss */
+ psit_getToken(psit_file,psit_current_token,
+ sizeof(psit_current_token), wscomma);
+ sscanf(psit_current_token, "%02d:%02d:%02d",
+ &(tmTime.tm_hour) , &(tmTime.tm_min),
+ &(tmTime.tm_sec));
+
+ tmTime.tm_isdst = 0;
+ time_t dateTime = mkgmtime(&tmTime);
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace);
+
+ if ((strcmp(psit_current_token, "1") == 0) || (track_head == nullptr)) {
+ track_head = new route_head;
+ /* Add a number to the track name. With Garmins, the "first"
+ tracklog is usually ACTIVE LOG
+ the second is ACTIVE LOG001 and so on */
+ if (trk_num > 0) {
+ track_head->rte_name = QString::asprintf("%s%03d", trkname, trk_num);
+ } else {
+ track_head->rte_name = trkname;
+ }
+ trk_num++;
+ track_add_head(track_head);
+ }
+
+ thisWaypoint->SetCreationTime(dateTime);
+ track_add_wpt(track_head, thisWaypoint);
+
+ if (gbfeof(psit_file)) {
+ break;
+ }
+
+ psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
+ } else {
+ break;
+ }
+ }
+}
+
+/*
+ * write out to file a tracklog header
+ * MRCB
+ */
+static void
+psit_trackhdr_w(gbfile* psit_file, const route_head* trk)
+{
+ QString tname;
+ time_t uniqueValue = 0;
+
+ if (psit_track_state == 2) {
+ /* total nodes (waypoints) this track */
+ //if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */
+ if (true) {
+
+ unsigned int trk_datapoints = 0;
+ foreach (const Waypoint* testwpt, trk->waypoint_list) {
+ if (trk_datapoints == 0) {
+ uniqueValue = testwpt->GetCreationTime().toTime_t();
+ }
+ trk_datapoints++;
+ }
+
+ if (uniqueValue == 0) {
+ uniqueValue = current_time().toTime_t();
+ }
+
+ /* track name */
+ if (trk->rte_name.isEmpty()) {
+ tname = QString("Track%1").arg((uint) uniqueValue, 4, 16, QChar('0'));
+ } else {
+ tname = trk->rte_name;
+ }
+
+ /* check for psitrex comment sign; replace with '$' */
+ tname = tname.replace(QChar('#'), QChar('$'));
+
+ gbfputs(QString("Track: %1\n").arg(tname), psit_file);
+ }
+ }
+ psit_track_state = 1;
+}
+
+static void
+psit_trackhdr_w_wrapper(const route_head* trk)
+{
+ psit_trackhdr_w(psit_file_out, trk);
+}
+
+
+/*
+ * write out to file a tracklog datapoint
+ * MRCB
+ */
+static void
+psit_trackdatapoint_w(gbfile* psit_file, const Waypoint* wpt)
+{
+ time_t t = wpt->GetCreationTime().toTime_t();
+ struct tm* tmTime = gmtime(&t);
+
+ gbfprintf(psit_file, "%11.6f,%11.6f,",
+ wpt->latitude,
+ wpt->longitude);
+
+ if (wpt->altitude == unknown_alt) {
+ gbfprintf(psit_file, "********, ");
+ } else
+ gbfprintf(psit_file, "%8.2f, ",
+ wpt->altitude);
+
+ /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */
+ gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,",
+ tmTime->tm_mday,
+ tmTime->tm_mon+1,
+ tmTime->tm_year % 100,
+ tmTime->tm_hour,
+ tmTime->tm_min,
+ tmTime->tm_sec);
+
+ gbfprintf(psit_file," %d\n", psit_track_state);
+ psit_track_state = 0;
+}
+
+static void
+psit_trackdatapoint_w_wrapper(const Waypoint* wpt)
+{
+ psit_trackdatapoint_w(psit_file_out, wpt);
+}
+
+
+static void
+psit_read()
+{
+ Waypoint* wpt;
+ route_head* rte;
+ route_head* trk;
+
+#ifdef DUMP_ICON_TABLE
+ printf("static icon_mapping_t icon_table[] = {\n");
+#endif
+
+ psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace);
+
+ do {
+ if (strlen(psit_current_token) == 0) {
+ break;
+ }
+
+ if (strcmp(psit_current_token, "Track:") == 0) {
+ if (global_opts.objective == trkdata) {
+ psit_track_r(psit_file_in, &trk);
+ } else {
+ break; /* psitrex files only have one format in; */
+ }
+ /* if this is a track file and we don't want them, them bail out */
+ } else if (strcmp(psit_current_token, "Route:") == 0) {
+ if (global_opts.objective == rtedata) {
+ psit_route_r(psit_file_in, &rte);
+ } else {
+ break; /* ditto, but for routes */
+ }
+ } else {
+ /* Must be waypoints in this file */
+ if (global_opts.objective == wptdata) {
+ psit_waypoint_r(psit_file_in, &wpt);
+#ifdef DUMP_ICON_TABLE
+ printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname);
+#endif
+
+ } else {
+ break;
+ }
+ }
+ } while (!gbfeof(psit_file_in));
+
+#ifdef DUMP_ICON_TABLE
+ printf("\t{ -1, NULL },\n");
+ printf("};\n");
+#endif
+}
+
+static void
+psit_write()
+{
+ int short_length;
+
+ if (snlen) {
+ short_length = atoi(snlen);
+ } else {
+ short_length = 10;
+ }
+
+ mkshort_handle = mkshort_new_handle();
+
+ setshort_length(mkshort_handle, short_length);
+ setshort_whitespace_ok(mkshort_handle, 0);
+
+ psit_track_state = 2;
+
+ if (global_opts.objective == wptdata) {
+ waypt_disp_all(psit_waypoint_w_wrapper);
+ }
+ if (global_opts.objective == rtedata) {
+ route_disp_all(psit_routehdr_w_wrapper, nullptr, psit_waypoint_w_wrapper);
+ }
+ if (global_opts.objective == trkdata) {
+ track_disp_all(psit_trackhdr_w_wrapper,
+ nullptr, psit_trackdatapoint_w_wrapper);
+ }
+
+ mkshort_del_handle(&mkshort_handle);
+
+}
+
+ff_vecs_t psit_vecs = {
+ ff_type_file,
+ FF_CAP_RW_ALL,
+ psit_rd_init,
+ psit_wr_init,
+ psit_rd_deinit,
+ psit_wr_deinit,
+ psit_read,
+ psit_write,
+ nullptr,
+ &psit_args,
+ CET_CHARSET_ASCII, 0 /* CET-REVIEW */
+ , NULL_POS_OPS,
+ nullptr
+};
<ClCompile Include="pocketfms_wp.cc" />\r
<ClCompile Include="polygon.cc" />\r
<ClCompile Include="position.cc" />\r
- <ClCompile Include="psitrex.cc" />\r
<ClCompile Include="radius.cc" />\r
<ClCompile Include="random.cc" />\r
<ClCompile Include="raymarine.cc" />\r
+++ /dev/null
-/*
- Access to PsiTrex text files.
- Based on information provided by Ian Cowley.
-
- Copyright (C) 2003 Mark Bradley, mrcb.gpsb@osps.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <cctype> // for isspace
-#include <cstdio> // for sscanf, EOF, size_t
-#include <cstdlib> // for atof, atoi
-#include <cstring> // for strcmp, strlen, strcpy
-#include <ctime> // for gmtime
-
-#include <QtCore/QChar> // for QChar
-#include <QtCore/QLatin1String> // for QLatin1String
-#include <QtCore/QString> // for QString
-#include <QtCore/QtGlobal> // for foreach, uint
-
-#include "defs.h"
-#include "garmin_tables.h" // for gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, PCX
-#include "gbfile.h" // for gbfprintf, gbfeof, gbfile, gbfgetc, gbfclose, gbfgets, gbfopen, gbfputs
-#include "src/core/datetime.h" // for DateTime
-
-
-#define MYNAME "PSITREX"
-
-enum psit_tokenSep_type {
- ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */
- EOL, /* don't skip spaces and tabs to start; end on EOL */
- comma, /* skip spaces & tabs to start; ends on comma or EOL */
- whitespace, /* skip spaces & tabs to start; ends on white space or EOL */
- wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */
-};
-
-struct psit_icon_mapping_t {
- int value;
- const char* icon;
-};
-
-static gbfile* psit_file_in;
-static gbfile* psit_file_out;
-static short_handle mkshort_handle;
-
-/* 2 = not written any tracks out
- 1 = change of track to write out track header
- 0 = in the middle of writing out track datapoints, so don't write a header */
-static int psit_track_state = 2;
-
-static char psit_current_token[256];
-
-static char* snlen;
-
-static
-QVector<arglist_t> psit_args = {
- /* {"snlen", &snlen, "Length of generated shortnames",
- NULL, ARGTYPE_INT, "1", NULL }, */
-};
-
-/* Taken from PsiTrex 1.13 */
-static
-const psit_icon_mapping_t psit_icon_value_table[] = {
- { 0x00, "anchor" },
- { 0x06, "dollar" },
- { 0x07, "fish" },
- { 0x08, "fuel" },
- { 0x0a, "house" },
- { 0x0b, "knife" },
- { 0x0d, "mug" },
- { 0x0e, "skull" },
- { 0x12, "wpt_dot" },
- { 0x13, "wreck" },
- { 0x15, "mob" },
- { 0x0096, "boat_ramp" },
- { 0x0097, "camp" },
- { 0x0098, "restrooms" },
- { 0x0099, "showers" },
- { 0x009a, "drinking_wtr" },
- { 0x009b, "phone" },
- { 0x009c, "1st_aid" },
- { 0x009d, "info" },
- { 0x009e, "parking" },
- { 0x009f, "park" },
- { 0x00a0, "picnic" },
- { 0x00a1, "scenic" },
- { 0x00a2, "skiing" },
- { 0x00a3, "swimming" },
- { 0x00a4, "dam" },
- { 0x00a6, "danger" },
- { 0x00a9, "ball" },
- { 0x00aa, "car" },
- { 0x00ab, "deer" },
- { 0x00ac, "shpng_cart" },
- { 0x00ad, "lodging" },
- { 0x00ae, "mine" },
- { 0x00af, "trail_head" },
- { 0x00b0, "truck_stop" },
- { 0x00b2, "flag" },
- { 0x2005, "golf" },
- { 0x2006, "sml_cty" },
- { 0x2007, "med_cty" },
- { 0x2008, "lrg_cty" },
- { 0x200c, "amuse_pk" },
- { 0x200d, "bowling" },
- { 0x200e, "car_rental" },
- { 0x200f, "car_repair" },
- { 0x2010, "fastfood" },
- { 0x2011, "fitness" },
- { 0x2012, "movie" },
- { 0x2013, "museum" },
- { 0x2014, "pharmacy" },
- { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */
- { 0x2016, "post_ofc" },
- { 0x2017, "rv_park" },
- { 0x2018, "school" },
- { 0x2019, "stadium" },
- { 0x201a, "store" },
- { 0x201b, "zoo" },
- { 0x201c, "gas_plus" },
- { 0x201d, "faces" },
- { 0x2022, "weigh_sttn" },
- { 0x2023, "toll_booth" },
- { 0x2029, "bridge" },
- { 0x202a, "building" },
- { 0x202b, "cemetery" },
- { 0x202c, "church" },
- { 0x202e, "crossing" },
- { 0x2032, "oil_field" },
- { 0x2033, "tunnel" },
- { 0x2035, "forest" },
- { 0x2036, "summit" },
- { 0x203f, "geocache" },
- { 0x2040, "geocache_fnd" },
- { 0x4000, "airport" },
- { 0x4007, "tall_tower" },
- { 0x4008, "short_tower" },
- { 0x4009, "glider" },
- { 0x400a, "ultralight" },
- { 0x400b, "parachute" },
- { 0x4012, "seaplane" },
- { -1, nullptr }
-};
-
-static const char*
-psit_find_desc_from_icon_number(const int icon)
-{
- for (const psit_icon_mapping_t* i = psit_icon_value_table; i->icon; i++) {
- if (icon == i->value) {
- return i->icon;
- }
- }
- return "";
-}
-
-static int
-psit_find_icon_number_from_desc(const char* desc)
-{
- int def_icon = 18;
-
- if (!desc) {
- return def_icon;
- }
-
- for (const psit_icon_mapping_t* i = psit_icon_value_table; i->icon; i++) {
- if (case_ignore_strcmp(desc,i->icon) == 0) {
- return i->value;
- }
- }
- if (atoi(desc) > 0) {
- return atoi(desc);
- }
- return def_icon;
-}
-
-static void
-psit_rd_init(const QString& fname)
-{
- psit_file_in = gbfopen(fname, "r", MYNAME);
-}
-
-static void
-psit_rd_deinit()
-{
- gbfclose(psit_file_in);
-}
-
-static void
-psit_wr_init(const QString& fname)
-{
- psit_file_out = gbfopen(fname, "w", MYNAME);
-}
-
-static void
-psit_wr_deinit()
-{
- gbfclose(psit_file_out);
-}
-
-/*
- * get characters until and including terminating NULL from psit_file_in
- * and write into buf.
- */
-static void
-psit_getToken(gbfile* psit_file, char* buf, size_t sz, psit_tokenSep_type delimType)
-{
- int c = -1;
-
- *buf = 0;
-
- if (delimType != EOL) {
- while ((c = gbfgetc(psit_file)) != EOF) {
- if (!isspace(c)) {
- break;
- }
- }
- }
-
- if (gbfeof(psit_file)) {
- return;
- }
-
- if (delimType == EOL) {
- c = gbfgetc(psit_file);
- }
-
- if (c == '#') {
- if (gbfgets(buf, sz, psit_file) == nullptr) {
- *buf = 0;
- return;
- }
- /* use recursion to skip multiple comment lines or just to return the next token */
- psit_getToken(psit_file, buf, sz, delimType);
- return;
- }
-
- if ((delimType == EOL) || (delimType == ltrimEOL)) {
- *buf = c;
- buf++;
- gbfgets(buf, sz-1, psit_file);
- return;
- }
-
- while (sz--) {
- *buf++ = c;
- if ((c = gbfgetc(psit_file)) == EOF) {
- *buf = 0;
- return;
- }
- if (((c == 0) || isspace(c)) &&
- ((delimType == whitespace) || (delimType == wscomma))) {
- *buf = 0;
- return;
- }
- if (((delimType == comma) || (delimType == wscomma)) &&
- (c == ',')) {
- *buf = 0;
- return;
- }
- }
-}
-
-
-/*
- * test if a token is known
- *
- */
-static int
-psit_isKnownToken(char* buf)
-{
- if (strcmp(buf, "Track:") == 0) {
- return 0;
- }
- if (strcmp(buf, "Route:") == 0) {
- return 0;
- }
- if (strcmp(buf, "Waypoint:") == 0) {
- return 0;
- }
- if (strcmp(buf, "Map:") == 0) {
- return 0;
- }
- return 1;
-}
-
-/*
- * read in from file a waypoint record
- * MRCB
- */
-static void
-psit_waypoint_r(gbfile* psit_file, Waypoint**)
-{
- if (strlen(psit_current_token) > 0) {
- auto* thisWaypoint = new Waypoint;
-
- thisWaypoint->latitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- thisWaypoint->longitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- if (psit_current_token[0] == '*') {
- thisWaypoint->altitude = unknown_alt;
- } else {
- thisWaypoint->altitude = atof(psit_current_token);
- }
-
- /* the name */
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- rtrim(psit_current_token);
- thisWaypoint->shortname = psit_current_token;
- thisWaypoint->description = "";
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
- rtrim(psit_current_token);
- /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */
- /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */
- int garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token);
- thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX);
-
- waypt_add(thisWaypoint);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
- }
-}
-
-/*
- * write out to file a waypoint record
- * MRCB
- */
-static void
-psit_waypoint_w(gbfile* psit_file, const Waypoint* wpt)
-{
- gbfprintf(psit_file, "%11.6f,%11.6f,",
- wpt->latitude,
- wpt->longitude);
-
- if (wpt->altitude == unknown_alt) {
- gbfprintf(psit_file, "********,");
- } else
- gbfprintf(psit_file, "%8.2f,",
- wpt->altitude);
-
- const char* ident = global_opts.synthesize_shortnames ?
- mkshort(mkshort_handle, "WPT", false) :
- xstrdup(wpt->shortname);
-
- gbfprintf(psit_file, " %-6s, ", ident);
- xfree(ident);
-
- int icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX);
-
- if (get_cache_icon(wpt) && wpt->icon_descr.compare(QLatin1String("Geocache Found")) != 0) {
- icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX);
- }
-
- ident = psit_find_desc_from_icon_number(icon);
- if (strlen(ident) == 0) {
- gbfprintf(psit_file, "%1d\n", icon);
- } else {
- gbfprintf(psit_file, "%s\n", ident);
- }
-
-}
-
-static void
-psit_waypoint_w_wrapper(const Waypoint* wpt)
-{
- psit_waypoint_w(psit_file_out, wpt);
-}
-
-/*
- * read in from file a route record
- * MRCB
- */
-static void
-psit_route_r(gbfile* psit_file, route_head** rte)
-{
- char rtename[256];
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
-
- if (strlen(psit_current_token) == 0) {
- strcpy(rtename, "ROUTE");
- } else {
- strcpy(rtename, psit_current_token);
- }
-
- rtrim(rtename);
-
- auto* rte_head = new route_head;
- rte_head->rte_name = rtename;
- route_add_head(rte_head);
- *rte = rte_head;
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
-
- while (psit_isKnownToken(psit_current_token) != 0) {
- if (strlen(psit_current_token) > 0) {
- auto* thisWaypoint = new Waypoint;
-
- thisWaypoint->latitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- thisWaypoint->longitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- if (psit_current_token[0] == '*') {
- thisWaypoint->altitude = unknown_alt;
- } else {
- thisWaypoint->altitude = atof(psit_current_token);
- }
-
- /* the name */
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- rtrim(psit_current_token);
- thisWaypoint->shortname = psit_current_token;
- thisWaypoint->description = "";
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
- rtrim(psit_current_token);
- /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */
- /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */
- int garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token);
- thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX);
-
- route_add_wpt(rte_head, thisWaypoint);
-
- if (gbfeof(psit_file)) {
- break;
- }
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
- } else {
- break;
- }
- }
-}
-
-/*
- * write out to file a route header
- * MRCB
- */
-static void
-psit_routehdr_w(gbfile* psit_file, const route_head* rte)
-{
- QString rname;
-
- /* total nodes (waypoints) this route */
- //if (rte->waypoint_list.next) {
- if (true) {
- // this test doesn't do what I w ant i.e test if this is a valid
- // route - treat as a placeholder for now .
- time_t uniqueValue = 0;
- unsigned int rte_datapoints = 0;
- foreach (const Waypoint* testwpt, rte->waypoint_list) {
- if (rte_datapoints == 0) {
- uniqueValue = testwpt->GetCreationTime().toTime_t();
- }
- rte_datapoints++;
- }
-
- if (uniqueValue == 0) {
- uniqueValue = current_time().toTime_t();
- }
-
- /* route name */
- if (rte->rte_name.isEmpty()) {
- rname = QString("Route%1").arg((uint) uniqueValue, 4, 16, QChar('0'));
- } else {
- rname = rte->rte_name;
- }
- /* check for psitrex comment sign; replace with '$' */
- rname = rname.replace(QChar('#'), QChar('$'));
-
- gbfputs(QString("Route: %1\n").arg(rname), psit_file);
- }
-}
-
-static void
-psit_routehdr_w_wrapper(const route_head* rte)
-{
- psit_routehdr_w(psit_file_out, rte);
-}
-
-
-/*
- * read in from file a track record
- * MRCB
- */
-static void
-psit_track_r(gbfile* psit_file, route_head**)
-{
- char trkname[256];
-
- struct tm tmTime;
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL);
- if (strlen(psit_current_token) == 0) {
- strcpy(trkname, "TRACK");
- } else {
- strcpy(trkname, psit_current_token);
- }
-
- rtrim(trkname);
-
- unsigned int trk_num = 0;
- route_head* track_head = nullptr;
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
-
- while (psit_isKnownToken(psit_current_token) != 0) {
- if (strlen(psit_current_token) > 0) {
- auto* thisWaypoint = new Waypoint;
-
- thisWaypoint->latitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- thisWaypoint->longitude = atof(psit_current_token);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma);
- if (psit_current_token[0] == '*') {
- thisWaypoint->altitude = unknown_alt;
- } else {
- thisWaypoint->altitude = atof(psit_current_token);
- }
-
- /* date portion of the date time DD/MM/YY */
- psit_getToken(psit_file, psit_current_token,
- sizeof(psit_current_token), whitespace);
- sscanf(psit_current_token, "%02d/%02d/%02d",
- &(tmTime.tm_mday) , &(tmTime.tm_mon),
- &(tmTime.tm_year));
-
- /* years are less 1900 in the tm struct */
- tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100);
- /* months are 0 to 11 in the tm struct */
- tmTime.tm_mon--;
- /* time portion of the date time hh:mm:ss */
- psit_getToken(psit_file,psit_current_token,
- sizeof(psit_current_token), wscomma);
- sscanf(psit_current_token, "%02d:%02d:%02d",
- &(tmTime.tm_hour) , &(tmTime.tm_min),
- &(tmTime.tm_sec));
-
- tmTime.tm_isdst = 0;
- time_t dateTime = mkgmtime(&tmTime);
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace);
-
- if ((strcmp(psit_current_token, "1") == 0) || (track_head == nullptr)) {
- track_head = new route_head;
- /* Add a number to the track name. With Garmins, the "first"
- tracklog is usually ACTIVE LOG
- the second is ACTIVE LOG001 and so on */
- if (trk_num > 0) {
- track_head->rte_name = QString::asprintf("%s%03d", trkname, trk_num);
- } else {
- track_head->rte_name = trkname;
- }
- trk_num++;
- track_add_head(track_head);
- }
-
- thisWaypoint->SetCreationTime(dateTime);
- track_add_wpt(track_head, thisWaypoint);
-
- if (gbfeof(psit_file)) {
- break;
- }
-
- psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma);
- } else {
- break;
- }
- }
-}
-
-/*
- * write out to file a tracklog header
- * MRCB
- */
-static void
-psit_trackhdr_w(gbfile* psit_file, const route_head* trk)
-{
- QString tname;
- time_t uniqueValue = 0;
-
- if (psit_track_state == 2) {
- /* total nodes (waypoints) this track */
- //if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */
- if (true) {
-
- unsigned int trk_datapoints = 0;
- foreach (const Waypoint* testwpt, trk->waypoint_list) {
- if (trk_datapoints == 0) {
- uniqueValue = testwpt->GetCreationTime().toTime_t();
- }
- trk_datapoints++;
- }
-
- if (uniqueValue == 0) {
- uniqueValue = current_time().toTime_t();
- }
-
- /* track name */
- if (trk->rte_name.isEmpty()) {
- tname = QString("Track%1").arg((uint) uniqueValue, 4, 16, QChar('0'));
- } else {
- tname = trk->rte_name;
- }
-
- /* check for psitrex comment sign; replace with '$' */
- tname = tname.replace(QChar('#'), QChar('$'));
-
- gbfputs(QString("Track: %1\n").arg(tname), psit_file);
- }
- }
- psit_track_state = 1;
-}
-
-static void
-psit_trackhdr_w_wrapper(const route_head* trk)
-{
- psit_trackhdr_w(psit_file_out, trk);
-}
-
-
-/*
- * write out to file a tracklog datapoint
- * MRCB
- */
-static void
-psit_trackdatapoint_w(gbfile* psit_file, const Waypoint* wpt)
-{
- time_t t = wpt->GetCreationTime().toTime_t();
- struct tm* tmTime = gmtime(&t);
-
- gbfprintf(psit_file, "%11.6f,%11.6f,",
- wpt->latitude,
- wpt->longitude);
-
- if (wpt->altitude == unknown_alt) {
- gbfprintf(psit_file, "********, ");
- } else
- gbfprintf(psit_file, "%8.2f, ",
- wpt->altitude);
-
- /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */
- gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,",
- tmTime->tm_mday,
- tmTime->tm_mon+1,
- tmTime->tm_year % 100,
- tmTime->tm_hour,
- tmTime->tm_min,
- tmTime->tm_sec);
-
- gbfprintf(psit_file," %d\n", psit_track_state);
- psit_track_state = 0;
-}
-
-static void
-psit_trackdatapoint_w_wrapper(const Waypoint* wpt)
-{
- psit_trackdatapoint_w(psit_file_out, wpt);
-}
-
-
-static void
-psit_read()
-{
- Waypoint* wpt;
- route_head* rte;
- route_head* trk;
-
-#ifdef DUMP_ICON_TABLE
- printf("static icon_mapping_t icon_table[] = {\n");
-#endif
-
- psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace);
-
- do {
- if (strlen(psit_current_token) == 0) {
- break;
- }
-
- if (strcmp(psit_current_token, "Track:") == 0) {
- if (global_opts.objective == trkdata) {
- psit_track_r(psit_file_in, &trk);
- } else {
- break; /* psitrex files only have one format in; */
- }
- /* if this is a track file and we don't want them, them bail out */
- } else if (strcmp(psit_current_token, "Route:") == 0) {
- if (global_opts.objective == rtedata) {
- psit_route_r(psit_file_in, &rte);
- } else {
- break; /* ditto, but for routes */
- }
- } else {
- /* Must be waypoints in this file */
- if (global_opts.objective == wptdata) {
- psit_waypoint_r(psit_file_in, &wpt);
-#ifdef DUMP_ICON_TABLE
- printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname);
-#endif
-
- } else {
- break;
- }
- }
- } while (!gbfeof(psit_file_in));
-
-#ifdef DUMP_ICON_TABLE
- printf("\t{ -1, NULL },\n");
- printf("};\n");
-#endif
-}
-
-static void
-psit_write()
-{
- int short_length;
-
- if (snlen) {
- short_length = atoi(snlen);
- } else {
- short_length = 10;
- }
-
- mkshort_handle = mkshort_new_handle();
-
- setshort_length(mkshort_handle, short_length);
- setshort_whitespace_ok(mkshort_handle, 0);
-
- psit_track_state = 2;
-
- if (global_opts.objective == wptdata) {
- waypt_disp_all(psit_waypoint_w_wrapper);
- }
- if (global_opts.objective == rtedata) {
- route_disp_all(psit_routehdr_w_wrapper, nullptr, psit_waypoint_w_wrapper);
- }
- if (global_opts.objective == trkdata) {
- track_disp_all(psit_trackhdr_w_wrapper,
- nullptr, psit_trackdatapoint_w_wrapper);
- }
-
- mkshort_del_handle(&mkshort_handle);
-
-}
-
-ff_vecs_t psit_vecs = {
- ff_type_file,
- FF_CAP_RW_ALL,
- psit_rd_init,
- psit_wr_init,
- psit_rd_deinit,
- psit_wr_deinit,
- psit_read,
- psit_write,
- nullptr,
- &psit_args,
- CET_CHARSET_ASCII, 0 /* CET-REVIEW */
- , NULL_POS_OPS,
- nullptr
-};
+++ /dev/null
-
-# PsiTrex. A text format that can't be handled by XCSV due to context of
-# data based on other data values in the file
-# Waypoints first
-rm -f ${TMPDIR}/psit-ww.txt ${TMPDIR}/psit-ww.mps
-gpsbabel -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource -F ${TMPDIR}/psit-ww.mps
-gpsbabel -i mapsource -f ${TMPDIR}/psit-ww.mps -o psitrex -F ${TMPDIR}/psit-ww.txt
-compare ${REFERENCE}/psitwpts.txt ${TMPDIR}/psit-ww.txt
-
-# Now test correct "empty" handling - ask for routes when there aren't any
-# Uses mapsource as the empty handling for this has already happened above
-rm -f ${TMPDIR}/psit-wr.mps
-gpsbabel -r -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-wr.mps
-compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-wr.mps
-
-# Routes next
-rm -f ${TMPDIR}/psit-rr.txt ${TMPDIR}/psit-rr.mps
-gpsbabel -r -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource -F ${TMPDIR}/psit-rr.mps
-gpsbabel -r -i mapsource -f ${TMPDIR}/psit-rr.mps -o psitrex -F ${TMPDIR}/psit-rr.txt
-compare ${REFERENCE}/route/psitrtes.txt ${TMPDIR}/psit-rr.txt
-
-# Now test correct "empty" handling - ask for tracks when there aren't any
-# Uses mapsource as the empty handling for this has already happened above
-rm -f ${TMPDIR}/psit-rt.mps
-gpsbabel -t -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-rt.mps
-compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-rt.mps
-
-# Tracks last
-rm -f ${TMPDIR}/psit-tt.txt ${TMPDIR}/psit-tt.mps
-gpsbabel -t -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource -F ${TMPDIR}/psit-tt.mps
-gpsbabel -t -i mapsource -f ${TMPDIR}/psit-tt.mps -o psitrex -F ${TMPDIR}/psit-tt.txt
-compare ${REFERENCE}/track/psittrks.txt ${TMPDIR}/psit-tt.txt
-
-# Now test correct "empty" handling - ask for waypoints when there aren't any
-# Uses mapsource as the empty handling for this has already happened above
-rm -f ${TMPDIR}/psit-tw.mps
-gpsbabel -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-tw.mps
-compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-tw.mps
-
extern ff_vecs_t easygps_vecs;
extern ff_vecs_t saroute_vecs;
extern ff_vecs_t navicache_vecs;
-extern ff_vecs_t psit_vecs;
extern ff_vecs_t gpl_vecs;
extern ff_vecs_t text_vecs;
extern ff_vecs_t html_vecs;
LegacyFormat easygps_fmt {easygps_vecs};
LegacyFormat saroute_fmt {saroute_vecs};
LegacyFormat navicache_fmt {navicache_vecs};
- LegacyFormat psit_fmt {psit_vecs};
#if SHAPELIB_ENABLED
ShapeFormat shape_fmt;
#endif
nullptr,
nullptr,
},
- { /* MRCB */
- &psit_fmt,
- "psitrex",
- "KuDaTa PsiTrex text",
- nullptr,
- nullptr,
- },
#if SHAPELIB_ENABLED
{
&shape_fmt,
+++ /dev/null
-
-
-
- <para>This is a text format created by KuDaTa's PsiTrex program
-for the Psion PDAs. The format can't be readily handled by XCSV, so
-this format is handled explicitly. Waypoints, routes and tracks are
-all handled, with icon names used corresponding to version 1.13 of
-PsiTrex. This module was contributed to GPSBabel by Mark
-Bradley.</para>
-